// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include <memory>
#include <set>
#include <string>
#include <string_view>

#include <tbir/runtime/algorithm/cedar.h>
#include <tbir/runtime/runtime_port.h>

namespace tbir::runtime {

    // Given a list of strings, finds the longest string which is a
    // prefix of a query.
    class PrefixMatcher {
#if defined(USE_CEDAR_UNORDERED)
        typedef cedar::da<int, -1, -2, false> cedar_t;
#else
        typedef cedar::da<int> cedar_t;
#endif
    public:
        explicit PrefixMatcher(const std::set<std::string> &dic);

        // Finds the longest string in dic, which is a prefix of `w`.
        // Returns the UTF8 byte length of matched string.
        // `found` is set if a prefix match exists.
        // If no entry is found, consumes one Unicode character.
        int PrefixMatch(const char *w, size_t w_len, bool *found = nullptr) const;

        int PrefixMatch(const std::string &w, bool *found = nullptr) const;

        // Finds the longest string in dic, which is a prefix of `w`.
        // Returns the UTF8 byte length of matched string.
        // `found` is set if a prefix match exists.
        // If no entry is found, return 0.
        int PrefixSearch(const char *w, size_t w_len) const;

    private:
        std::unique_ptr<cedar_t> trie_;
    };

}  // namespace tbir::runtime
